package other.edan.erp.k3;

import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.creekflow.ruleevent.RuleEvent;
import com.rkhd.platform.sdk.creekflow.ruleevent.RuleEventRequest;
import com.rkhd.platform.sdk.creekflow.ruleevent.RuleEventResponse;
import com.rkhd.platform.sdk.data.model.SalesOutReceipt__c;
import com.rkhd.platform.sdk.data.model.ShippingPersonnelSheet__c;
import com.rkhd.platform.sdk.data.model.UserRankRelation__c;
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.model.OperateResult;
import com.rkhd.platform.sdk.service.XoqlService;
import org.apache.commons.lang.StringUtils;
import other.edan.erp.utils.HCXObjectService;
import other.edan.erp.utils.ResultVo;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 计算销售出库模块字段值
 * @Author: 黎炎松
 * @Date: 2024/11/20 15:41
 */
public class CalcSalesOutField implements RuleEvent {
    private static final XoqlService xoqlService = XoqlService.instance();
    private static final List<String> businessDept = Arrays.asList("00100303", "0010030301", "0010030302", "0010030305"); // 业务发展部 - 部门编码
    private static final List<String> animalDept = Arrays.asList("0010030304", "001003030403", "001003030402", "001003030401"); // 动物医疗 - 部门编码
    private static final Long SZLB = 3380939796880036L; // 深圳理邦智慧健康发展有限公司 (客户)
    private static final Long ZZFGS = 3351254576339569L; // 郑州分公司
    private static final Long NJB = 3351255169735252L; // 南京办
    private static final Long XAB = 3351254535576176L; // 西安办
    private static final Long HXS = 3438629294742166L; // 侯新士
    private static final Long ZFQ = 3438625885805126L; // 左方清
    private static final Long WJH = 3438626137086543L; // 王井辉

    private static final Logger LOGGER = LoggerFactory.getLogger();

    private static String LOGGER_MSG = "计算销售出库模块报表字段 ==> ";

    /**
     * 执行触发规则触发事件
     * @param request
     * @return
     * @throws ScriptBusinessException
     */
    @Override
    public RuleEventResponse execute(RuleEventRequest request) throws ScriptBusinessException {
        LOGGER.info(LOGGER_MSG + "执行触发事件");

        // 处理当前的出库
        Long dataId = request.getDataId();
        dealSalesOutField(dataId);

        // 处理出库关联的装机数据
        CalcInstallInfoField calcInstallInfoField = new CalcInstallInfoField();
        calcInstallInfoField.dealInstallBySalesOut(dataId);

        RuleEventResponse response = new RuleEventResponse();
        response.setSuccess(true);
        response.setMsg("success");
        return response;
    }

    public static void main(String[] args) throws ApiEntityServiceException {
        CalcSalesOutField calcSalesOutField = new CalcSalesOutField();
        calcSalesOutField.dealSalesOutField(3692027499616837L);
    }

    /**
     * 处理销售出库模块报表字段赋值
     * @param salesOutId
     * @return
     */
    public ResultVo dealSalesOutField(Long salesOutId) {
        try {
            LOGGER.info(LOGGER_MSG + "开始处理: " + salesOutId);
            SalesOutReceipt__c salesOut = new SalesOutReceipt__c();
            salesOut.setId(salesOutId);
            salesOut = HCXObjectService.get(salesOut);

            Long actualDepart = salesOut.getActualSector__c(); // 实际部门
            String processNo = salesOut.getProcessNo__c(); // 超声/检验报单企业微信审批流程编号 (手动输入)

            // 获取【业务员】所在部门
            Long salesman = salesOut.getSalesman__c();
            String departCode = "";
            if (salesman != null) {
                String sql = "select id,dimDepart.departCode as departCode from user where id = " + salesman;
                List<JSONObject> userList = xoqlService.query(sql).getRecords();
                if (userList.size() > 0) {
                    departCode = userList.get(0).getString("departCode");
                }
            }

            // 是否为业务发展部业绩
            Integer isYwfzbyj = getBusinessDepart(salesOut.getOriDepartment__c(), departCode);

            // 获取装机计算字段子表
            String sql = "select id,customItem25__c,salesOutReceiptDetails__c.productCode__c productLine,salesOutReceiptDetails__c.chanPinFenLei__c proxyProducts " +
                    " from shippingPersonnelSheet__c where entityType = 3533390342314578 and salesOutReceipt__c = " + salesOutId;
            List<JSONObject> shippingSheetList = HCXObjectService.queryAllUseXoql(sql);
            if (shippingSheetList != null && shippingSheetList.size() > 0) {
                // 获取外挂表:【部门-岗位关系】,根据产品线进行分组
                Map<Integer, JSONObject> positionRelationMap = new HashMap<>();
                if (actualDepart != null) {
                    sql = "select id,name,productLine__c,customItem3__c,customItem4__c,departmentName__c from positionRelationship__c where departmentName__c = " + actualDepart;
                    positionRelationMap = HCXObjectService.queryAllUseXoql(sql).stream().collect(Collectors.toMap(e -> e.getInteger("productLine__c"), e1 -> e1, (e, e1) -> e));
                }
                LOGGER.info(LOGGER_MSG + "positionRelationMap: " + positionRelationMap);

                // 获取外挂表:【用户-职级关系】
                String confirmingClerks = shippingSheetList.stream().map(v -> v.getString("customItem25__c")).collect(Collectors.joining(","));
                sql = String.format("select id,name,userName__c,job__c,userName__c,customItem11__c,customItem12__c,customItem13__c,customItem14__c,userLevel__c from userRankRelation__c " +
                        " where userName__c in (%s)", confirmingClerks);
                List<UserRankRelation__c> userRankRelationList = HCXObjectService.queryAll(sql);

                // 处理计算字段子表
                LOGGER.info(LOGGER_MSG + "处理明细表");
                List<ShippingPersonnelSheet__c> upSheetList =new ArrayList<>();
                for (JSONObject shippingSheet : shippingSheetList) {
                    ShippingPersonnelSheet__c upSheet = new ShippingPersonnelSheet__c();
                    UserRankRelation__c userRankRelation = userRankRelationList.stream().filter(v -> Objects.equals(v.getUserName__c(), shippingSheet.getLong("customItem25__c"))).findFirst().orElse(null);
                    LOGGER.info(LOGGER_MSG + "userRankRelation: " + userRankRelation);

                    Integer productLine = shippingSheet.getInteger("productLine"); // 实际产品线
                    // 是否动物产品
                    Integer isAnimalUse = getIsAnimalUse(departCode, shippingSheet.getInteger("proxyProducts"));
                    dealCalcField(upSheet, positionRelationMap, userRankRelation, productLine, processNo, actualDepart, isYwfzbyj, isAnimalUse);
                    upSheetList.add(upSheet);
                }

                // 保存明细表
                LOGGER.info(LOGGER_MSG + "保存明细表");
                HCXObjectService.updateBatch(upSheetList);
            }

            // 出库获取需要修改的字段
            SalesOutReceipt__c upSalesOut = new SalesOutReceipt__c();
            upSalesOut.setId(salesOutId);

            // 口径类别
            upSalesOut.setCaliberClass__c(getCaliberCate(salesOut));

            // 保存
            OperateResult update = HCXObjectService.update(upSalesOut);

            LOGGER.info(LOGGER_MSG + "update:" + update.getSuccess());
            LOGGER.info(LOGGER_MSG + "处理成功");
            return ResultVo.success("处理成功");
        } catch (ApiEntityServiceException e) {
            e.printStackTrace();
            LOGGER.error(LOGGER_MSG + "处理异常:" + e.getMessage());
            return ResultVo.error("处理异常: " + e.getMessage());
        }
    }

    /**
     * 计算出库计算字段
     *
     * @param upSheet
     * @param positionRelationMap
     * @param userRankRelation
     * @param productLine
     * @param processNo
     * @param actualDepart
     * @param isYwfzbyj
     * @param isAnimalUse
     */
    public static void dealCalcField(ShippingPersonnelSheet__c upSheet, Map<Integer, JSONObject> positionRelationMap,
                              UserRankRelation__c userRankRelation, Integer productLine, String processNo,
                              Long actualDepart, Integer isYwfzbyj, Integer isAnimalUse) {
        Long confirmingClerk = upSheet.getCustomItem25__c(); // 办事处确认业务员/装机人

        /**
         * 出货超声线省区/区域经理
         * 取值逻辑：
         *      1、如果产品线为“超声”，且“超声/检验报单企业微信审批流程编号”有值，同时满足上述两个条件时，该值为空；
         *      2、如果为产品线为“超声”，根据“实际部门“从“外挂表3”中取值；
         */
        Long csxqyjl = null;
        if (Objects.equals(productLine, 4) && positionRelationMap.containsKey(productLine) && StringUtils.isBlank(processNo)) {
            csxqyjl = positionRelationMap.get(productLine).getLong("customItem3__c");
        }
        upSheet.setCustomItem2__c(csxqyjl);

        // 出货检验线
        Long qyjj = null; // 出货检验线省区/区域经理
        Long dqjj = null; // 出货检验线大区经理
        if (Objects.equals(productLine, 5) && positionRelationMap.containsKey(productLine)) {
            JSONObject lineObj = positionRelationMap.get(productLine);
            qyjj = lineObj.getLong("customItem3__c");
            dqjj = lineObj.getLong("customItem4__c");
        }
        upSheet.setCustomItem3__c(qyjj);
        upSheet.setCustomItem4__c(dqjj);

        // 出货常规线
        Long xxzg = null; // 出货常规线销售主管/业务发展部省区经理
        Long gjzg = null; // 出货常规线高级主管/业务发展部区域经理
        Long fzr = null; // 出货办事处副主任
        Long fzbDqjj = null; // 出货业务发展部大区经理
        Long pdKhjj = null; // 出货盆底客户经理
        Long cssKhjj = null; // 出货超声线客户经理
        Long jyxKhjj = null; // 出货检验线客户经理
        Long fzbKhjj = null; // 出货常规线/业务发展部客户经理
        if (userRankRelation != null) {
            String userLevel = userRankRelation.getUserLevel__c(); // 员工级别

            // 出货常规线销售主管/业务发展部省区经理
            if (userLevel.contains("主管")) {
                xxzg = confirmingClerk;
            } else if (StringUtils.isBlank(processNo)) {
                xxzg = userRankRelation.getCustomItem11__c();
            }

            // 出货常规线高级主管/业务发展部区域经理
            if (userLevel.contains("高级主管")) {
                gjzg = confirmingClerk;
            } else if (StringUtils.isBlank(processNo)) {
                gjzg = userRankRelation.getCustomItem12__c();
            }

            // 出货办事处副主任
            if (userLevel.contains("副主任")) {
                fzr = confirmingClerk;
            } else if (StringUtils.isBlank(processNo)) {
                fzr = userRankRelation.getCustomItem13__c();

                // 如果没值，根据"实际部门"继续判断
                if (fzr == null) {

                    // 郑州分公司 & 产品线是 “监护”或“经颅”或“产科”或“妇科”或“心电”或“子宫复旧仪”，取值“侯新士”
                    if (Objects.equals(actualDepart, ZZFGS) && Arrays.asList(1, 2, 3, 9).contains(productLine)) {
                        fzr = HXS;
                    }

                    // 南京办 & 产品线是"盆底"，取值“左方清”
                    if (Objects.equals(actualDepart, NJB) && Objects.equals(productLine, 1)) {
                        fzr = ZFQ;
                    }

                    // 西安办 & 产品线是“盆底”或“彩超”或“黑白超”，办事处副主任取值“王井辉”
                    if (Objects.equals(actualDepart, XAB) && Arrays.asList(1, 5).contains(productLine)) {
                        fzr = WJH;
                    }

                }
            }

            // 出货业务发展部大区经理
            fzbDqjj = userLevel.contains("大区经理") ? confirmingClerk : userRankRelation.getCustomItem14__c();

            // 出货盆底客户经理
            if (userLevel.contains("职员级-盆底")) pdKhjj = confirmingClerk;

            // 出货盆底客户经理
            if (userLevel.contains("职员级-超声")) cssKhjj = confirmingClerk;

            // 出货检验线客户经理
            if (userLevel.contains("职员级-检验")) jyxKhjj = confirmingClerk;

            // 出货常规线/业务发展部客户经理
            if (userLevel.equals("职员级")) fzbKhjj = confirmingClerk;
        }
        upSheet.setCustomItem9__c(xxzg);
        upSheet.setCustomItem10__c(gjzg);
        upSheet.setCustomItem11__c(fzr);
        upSheet.setCustomItem12__c(fzbDqjj);
        upSheet.setCustomItem13__c(pdKhjj);
        upSheet.setCustomItem14__c(cssKhjj);
        upSheet.setCustomItem15__c(jyxKhjj);
        upSheet.setCustomItem16__c(fzbKhjj);
        upSheet.setYeWuFaZhan__c(isYwfzbyj); // 是否为业务发展部业绩 1:是 2:否
        upSheet.setDongWuChanPin__c(isAnimalUse); // 是否动物产品 1:是 2:否
    }

    /**
     * 是否为业务发展部业绩
     * @param oriDepartment
     * @param departCode
     * @return
     * @throws ApiEntityServiceException
     */
    public static Integer getBusinessDepart(String oriDepartment, String departCode) throws ApiEntityServiceException {
        if (StringUtils.isBlank(oriDepartment)) {
            return 2;
        }

        // 判断
        if (oriDepartment.contains("业务发展部") || businessDept.contains(departCode)) {
            // 原部门为“业务发展部”；
            return 1;
        }

        //else if (oriDepartment.contains("办事处") && businessDept.contains(departCode)) {
        //    // 原部门为”办事处“，且业务员所在的部门为 业务发展部
        //    return 1;
        //}

        return 2;
    }

    /**
     * 是否兽用
     * @param departCode
     * @param proxyProducts
     * @return
     * @throws ApiEntityServiceException
     */
    public static Integer getIsAnimalUse(String departCode, Integer proxyProducts) throws ApiEntityServiceException {
        if (animalDept.contains(departCode)) {
            return 1;
        }

        // 判断明细中的产品是否有产品中字段【代理产品分类】proxyProducts__c 值为兽用的数据 15,18,19,22,23,30
        if (proxyProducts != null && Arrays.asList(15,18,19,22,23,30).contains(proxyProducts)) {
            return 1;
        }

        return 2;
    }

    /**
     * 是否兽用
     * @param salesOutId
     * @param departCode
     * @return
     * @throws ApiEntityServiceException
     */
    public static Integer getAnimalUse(Long salesOutId, String departCode) throws ApiEntityServiceException {
        if (animalDept.contains(departCode)) {
            return 1;
        }

        // 判断明细中的产品是否有产品中字段【代理产品分类】proxyProducts__c 值为兽用的数据 13
        //String sql = " select id from salesOutReceiptDetails__c where porductName__c.proxyProducts__c = 13 and  salesOutReceipt__c = " + salesOutId;
        String sql = " select id from salesOutReceiptDetails__c where porductName__c.proxyProducts__c in (15,18,19,22,23,30) and  salesOutReceipt__c = " + salesOutId;
        if (xoqlService.query(sql).getRecords().size() > 0) {
            return 1;
        }
        return 2;
    }


    /**
     * 口径类别
     * @param salesOut 1：集团 2：总部 3：其他
     * @return
     * @throws ApiEntityServiceException
     */
    public Integer getCaliberCate(SalesOutReceipt__c salesOut) throws ApiEntityServiceException {

        // 各类数据源为“智慧健康”或“医疗信息化”，口径类别维护为"集团"；
        Integer variousDataSources = salesOut.getVariousDataSources__c();
        if (variousDataSources != null && Arrays.asList(3, 6).contains(variousDataSources)) {
            return 1;
        }

        // 客户名称为“深圳理邦智慧健康发展有限公司”，办事处确认业务员为"智慧健康",口径类别维护为"总部"
        if (Objects.equals(salesOut.getCustomerName__c(), SZLB)) {
            Long confirmingClerk = salesOut.getConfirmingClerk__c();
            String sql = "select id from user where informationForm__c = 2 and id = " + confirmingClerk;
            if (xoqlService.query(sql).getRecords().size() > 0) {
                return 2;
            }
        }

        return 3;
    }
}
